﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text;
using System.Reflection;

public class ConfigDatabase
{
    public int ID;
    
}

public class ConfigTable<TDatabase,T>: BaseManager<T> where TDatabase: ConfigDatabase, new() where T:new()
{
    //id,数据条目
    public Dictionary<int, TDatabase> _cache = new Dictionary<int, TDatabase>();
    public ConfigTable()
    {
        load("Config/" + GetType().ToString() + ".csv");
    }

    protected void load(string tablePath)
    {
        MemoryStream tableStream;
#if UNITY_EDITOR
        //开发期，读Project/Cofig
        var srcPath = Application.dataPath + "/../" + tablePath;
        tableStream = new MemoryStream(File.ReadAllBytes(srcPath));
#else
        //发布之后，读Resources/Config
        var table = Resources.Load<TextAsset>(tablePath);
        tableStream = new MemoryStream(table.bytes);
#endif
        using (var reader = new StreamReader(tableStream, Encoding.GetEncoding("gb2312")))
        {
            reader.ReadLine();//跳过注释
            //反射字段名
            var fieldNameStr=reader.ReadLine();
            var fieldNameArray = fieldNameStr.Split(',');
            List<FieldInfo> allFieldInfo = new List<FieldInfo>();
            foreach(var fieldName in fieldNameArray)
            {
                var fieldType = typeof(TDatabase).GetField(fieldName);
                if (fieldType == null)
                {
                    Debug.LogError("表中字段未在程序中定义"+fieldName);
                    continue;
                }
                allFieldInfo.Add(fieldType);
                
            }

            //下面是正式数据
            var lineStr = reader.ReadLine();
            while (lineStr != null)
            {
                //读到内存
                //configDB.ID = int.Parse(itemStrArray[0]);
                //prasetrItem(configDB, itemStrArray);

                //使用反射进行赋值
                TDatabase configDB = ReadLine(allFieldInfo, lineStr);

                _cache[configDB.ID] = configDB;

                lineStr = reader.ReadLine();

            }
        }
    }

    private static TDatabase ReadLine(List<FieldInfo> allFieldInfo, string lineStr)
    {
        var itemStrArray = lineStr.Split(',');
        var configDB = new TDatabase();

        for (int i = 0; i < allFieldInfo.Count; i++)
        {
            //Debug.Log(allFieldInfo[i]);
            var field = allFieldInfo[i];
            var data = itemStrArray[i];
            if (field.FieldType == typeof(int))
            {
                int fieldValue;
                if (!int.TryParse(data, out fieldValue))
                {
                    fieldValue = 0;
                }
                field.SetValue(configDB, fieldValue);
            }
            else if (field.FieldType == typeof(string))
            {
                field.SetValue(configDB, data);
            }
            else if (field.FieldType == typeof(float))
            {
                float fieldValue;
                if(!float.TryParse(data,out fieldValue))
                {
                    fieldValue = 0;
                }
                field.SetValue(configDB,fieldValue);
            }
            else if (field.FieldType == typeof(bool))
            {
                bool fieldValue;
                if (!bool.TryParse(data, out fieldValue))
                {
                    fieldValue = false;
                }
                field.SetValue(configDB,fieldValue);
            }
            //数组类型反射
            else if (field.FieldType == typeof(List<int>))
            {
                var list = new List<int>();
                foreach(var itemStr in data.Split('$'))
                {
                    int fieldValue;
                    if (!int.TryParse(itemStr, out fieldValue))
                    {
                        fieldValue = 0;
                    }
                    list.Add(fieldValue);
                }
                field.SetValue(configDB, list);
            }
            else if (field.FieldType == typeof(List<float>))
            {
                var list = new List<float>();
                foreach (var itemStr in data.Split('$'))
                {
                    float fieldValue;
                    if (!float.TryParse(itemStr, out fieldValue))
                    {
                        fieldValue = 0;
                    }
                    list.Add(fieldValue);
                }
                field.SetValue(configDB, list);
            }

            else if (field.FieldType == typeof(List<string>))
            {
                field.SetValue(configDB, new List<string>(data.Split('$')));
            }
           
        }

        return configDB;
    }

    //protected virtual void prasetrItem(TDatabase configDB, string[] itemStrArray)
    //{

    //}

    //检索器
    public TDatabase this[int index]
    {
        get
        {
            TDatabase db;
            _cache.TryGetValue(index, out db);
            return db;
        }
    }
    //返回所有数据给外部使用
    public Dictionary<int, TDatabase> GetAllRole()
    {
        return _cache;
    }
}
